﻿using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using Aeon.Configuration;
using Aeon.Emulator.Dos.VirtualFileSystem;

namespace Aeon.Emulator.Launcher
{
    /// <summary>
    /// Dialog for configuring a virtual drive.
    /// </summary>
    public partial class DriveProperties : Window
    {
        #region Private Static Fields
        /// <summary>
        /// The ViewCache dependency property key definition.
        /// </summary>
        private static readonly DependencyPropertyKey ViewCachePropertyKey = DependencyProperty.RegisterReadOnly("ViewCache", typeof(ConfigViewCache), typeof(DriveProperties), new PropertyMetadata(null));
        #endregion

        #region Public Static Fields
        /// <summary>
        /// The AvailableDriveLetters dependency property definition.
        /// </summary>
        public static readonly DependencyProperty AvailableDriveLettersProperty = DependencyProperty.Register("AvailableDriveLetters", typeof(IEnumerable<DriveLetter>), typeof(DriveProperties));
        /// <summary>
        /// The MountedDrive dependency property definition.
        /// </summary>
        public static readonly DependencyProperty MountedDriveProperty = DependencyProperty.Register("MountedDrive", typeof(MountedDrive), typeof(DriveProperties));
        /// <summary>
        /// The ViewCache dependency property definition.
        /// </summary>
        public static readonly DependencyProperty ViewCacheProperty = ViewCachePropertyKey.DependencyProperty;
        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the DriveProperties class.
        /// </summary>
        public DriveProperties()
        {
            InitializeComponent();
        }
        #endregion

        #region Public Properties
        /// <summary>
        /// Gets or sets the collection of available drive letters. This is a dependency property.
        /// </summary>
        public IEnumerable<DriveLetter> AvailableDriveLetters
        {
            get { return (IEnumerable<DriveLetter>)GetValue(AvailableDriveLettersProperty); }
            set { SetValue(AvailableDriveLettersProperty, value); }
        }
        /// <summary>
        /// Gets or sets the drive to edit. This is a dependency property.
        /// </summary>
        public MountedDrive MountedDrive
        {
            get { return (MountedDrive)GetValue(MountedDriveProperty); }
            set { SetValue(MountedDriveProperty, value); }
        }
        /// <summary>
        /// Gets the drive configuration view cache. This is a dependency property.
        /// </summary>
        public ConfigViewCache ViewCache
        {
            get { return (ConfigViewCache)GetValue(ViewCacheProperty); }
        }
        #endregion

        #region Protected Methods
        /// <summary>
        /// Invoked when a dependency property value has changed.
        /// </summary>
        /// <param name="e">Information about the event.</param>
        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);

            if(e.Property == MountedDriveProperty)
                OnMountedDriveChanged(e);
        }
        /// <summary>
        /// Invoked when the MountedDrive dependency property value has changed.
        /// </summary>
        /// <param name="e">Information about the event.</param>
        protected virtual void OnMountedDriveChanged(DependencyPropertyChangedEventArgs e)
        {
            var drive = (MountedDrive)e.NewValue;
            if(drive != null)
            {
                var cache = new ConfigViewCache(drive.DriveConfiguration);
                SetValue(ViewCachePropertyKey, cache);
            }
            else
                SetValue(ViewCachePropertyKey, null);
        }
        #endregion

        #region Event Handlers
        /// <summary>
        /// Invoked when the OK button is clicked.
        /// </summary>
        /// <param name="sender">Source of the event.</param>
        /// <param name="e">Information about the event.</param>
        private void OK_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
        }
        /// <summary>
        /// Invoked when the source combo box value has changed.
        /// </summary>
        /// <param name="sender">Source of the event.</param>
        /// <param name="e">Information about the event.</param>
        private void SourceComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var drive = this.MountedDrive;
            if(drive != null)
            {
                var view = (IDriveConfigurationView)this.ViewCache.SelectedConfigurationView;
                if(view != null)
                    drive.DriveConfiguration = view.DriveConfiguration;
            }
        }
        #endregion
    }
}
